package com.android.tripspins.app;

import android.app.ActionBar;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.database.DataSetObserver;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.provider.MediaStore;
import android.support.v4.widget.DrawerLayout;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewTreeObserver;
import android.widget.EditText;
import android.widget.GridView;
import android.widget.ImageButton;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import com.android.tripspins.app.adapter.AttachmentListAdapter;
import com.android.tripspins.app.bo.Attachment;
import com.android.tripspins.app.bo.Contact;
import com.android.tripspins.app.bo.CurrentWeather;
import com.android.tripspins.app.bo.Pin;
import com.android.tripspins.app.bo.Route;
import com.android.tripspins.app.bo.Trip;
import com.android.tripspins.app.bo.User;
import com.android.tripspins.app.dao.AttachmentDAO;
import com.android.tripspins.app.dao.PinDAO;
import com.android.tripspins.app.dao.TripDAO;
import com.android.tripspins.app.dao.UserDAO;
import com.android.tripspins.app.exception.NoConnectionException;
import com.android.tripspins.app.exception.OfflineModeException;
import com.android.tripspins.app.helper.ConstantsHelper;
import com.android.tripspins.app.helper.DbHelper;
import com.android.tripspins.app.helper.FILE_TYPE;
import com.android.tripspins.app.helper.FileHelper;
import com.android.tripspins.app.helper.HttpHelper;
import com.android.tripspins.app.helper.LocationHelper;
import com.android.tripspins.app.helper.MapsAPIHelper;
import com.android.tripspins.app.helper.MenuHelper;
import com.android.tripspins.app.helper.TRIP_STATUS;
import com.android.tripspins.app.helper.ThumbnailsHelper;
import com.android.tripspins.app.helper.WeatherHelper;
import com.android.tripspins.app.interfaces.OnTaskCompleted;
import com.android.tripspins.app.services.BackgroundPinGeneratorService;
import com.facebook.Session;
import com.facebook.SessionState;
import com.facebook.UiLifecycleHelper;
import com.facebook.model.GraphUser;
import com.google.android.gms.maps.CameraUpdate;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.LatLngBounds;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

public class NewPinActivity extends Activity implements OnTaskCompleted {


    CurrentWeather currWeather;
    WeatherHelper weatherHelper;
    LocationHelper locationHelper;
    SQLiteDatabase database;
    DbHelper dbHelper;
    Pin newPin;
    PinDAO pinDao;
    TripDAO tripDao;
    int purpose;
    Trip trip;
    Uri fileUri;
    GoogleMap map;

    ImageButton btnSave;
    EditText txtTitle;
    EditText txtNote;
    GridView lstAttachments;
    final MapsAPIHelper mapsHelper = new MapsAPIHelper(this);

    private UiLifecycleHelper uiHelper;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_new_pin);
        uiHelper = new UiLifecycleHelper(this, callback);
        uiHelper.onCreate(savedInstanceState);

        getActionBar().setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
        LayoutInflater inflator = (LayoutInflater) this .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        getActionBar().setCustomView(inflator.inflate(R.layout.new_pin_menu, null));
        getActionBar().setDisplayShowTitleEnabled(true);
        getActionBar().setDisplayHomeAsUpEnabled(true);
        getActionBar().setDisplayShowHomeEnabled(true);
        getActionBar().setHomeButtonEnabled(true);



        map = ((MapFragment) getFragmentManager().findFragmentById(R.id.map)).getMap();
        map.setMyLocationEnabled(true);

        dbHelper = new DbHelper(this);
        Intent myIntent = getIntent();
        purpose = myIntent.getIntExtra("param", ConstantsHelper.PIN_DEFAULT);
        try{
            newPin = savedInstanceState.getParcelable("newPin");
            fileUri = savedInstanceState.getParcelable("fileUri");
        }
        catch(Exception e){}

        UserDAO userDao = new UserDAO(database);
        tripDao = new TripDAO(database);
        User loggedUser = userDao.getLoggedUser();
        boolean isAuthenticated = loggedUser != null;

        MenuHelper.loadMenu(this, !(purpose == ConstantsHelper.PIN_START), isAuthenticated);

        database = dbHelper.getWritableDatabase();
        TripDAO tripDao = new TripDAO(database);
        if(purpose == ConstantsHelper.PIN_START)
            trip = new Trip();
        else
            trip = tripDao.getTrip();//Current Trip
        database.close();


        if(newPin == null){
            locationHelper = LocationHelper.getInstance(this, this);
            newPin = new Pin();
        }

        loadActivityViews();
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putParcelable("newPin", newPin);
        outState.putParcelable("fileUri",fileUri);
        uiHelper.onSaveInstanceState(outState);


    }

    public void updateMapLocation(LatLng currentLatLng)
    {
        try{
            map.clear();
            newPin.setLatLng(currentLatLng);
            weatherHelper = new WeatherHelper(this);
            weatherHelper.getWeather(currentLatLng);

            MarkerOptions markerOptions = mapsHelper.getMarker(currentLatLng);
            Marker marker = map.addMarker(markerOptions);

            LatLngBounds bounds = new LatLngBounds(currentLatLng,currentLatLng);
            final CameraUpdate location = CameraUpdateFactory.newLatLngBounds(bounds, 1000,1000,300);
            final CameraUpdate zoom = CameraUpdateFactory.newLatLngZoom(currentLatLng, 14.0f);
            MapFragment fragment = (MapFragment) getFragmentManager().findFragmentById(R.id.map);
            map.moveCamera(location);
            map.moveCamera(zoom);
            fragment.getView().getViewTreeObserver().addOnGlobalLayoutListener(
                    new ViewTreeObserver.OnGlobalLayoutListener() {
                        @Override
                        public void onGlobalLayout() {map.animateCamera(zoom);}});
        }catch(Exception e){}
    }

    @Override
    public void onPause() {
        super.onPause();
        uiHelper.onPause();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if(isFinishing()){
            FileHelper fileHelper = new FileHelper(this);
            fileHelper.cleanTempFolders();
        }
        uiHelper.onDestroy();
    }

    private Session.StatusCallback callback = new Session.StatusCallback() {
        @Override
        public void call(Session session, SessionState state, Exception exception) {
            onSessionStateChange(session, state, exception);
        }
    };


    private void onSessionStateChange(Session session, SessionState state, Exception exception) {

    }
    private void loadActivityViews()    {
        btnSave = (ImageButton)findViewById(R.id.menu_save_pin);
        txtTitle  = (EditText)findViewById(R.id.new_pin_edit_title);
        txtNote  = (EditText)findViewById(R.id.new_pin_edit_note);
        lstAttachments = (GridView)findViewById(R.id.new_pin_list_attachments);
        View.OnClickListener saveListener = new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                saveFinish();
            }
        };
        btnSave.setOnClickListener(saveListener);
        loadListAttachments();
        if(newPin.getLatLng() == null)
        {
            newPin.setLatLng(locationHelper.getPosition());
            if(newPin.getLatLng() != null)
                updateMapLocation(newPin.getLatLng());
        }
    }

    public void loadListAttachments()    {
        AttachmentListAdapter attachmentListAdapter = new AttachmentListAdapter(this, newPin.getAttachments());
        attachmentListAdapter.registerDataSetObserver(new DataSetObserver() {
            @Override
            public void onChanged() {
                super.onChanged();
            }
        });
        lstAttachments.setAdapter(attachmentListAdapter);

    }

    @Override
    protected void onResume() {
        super.onResume();
        loadListAttachments();
        uiHelper.onResume();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_add_pin_bottom, menu);
        return true;
    }

    @Override
    public void onTaskCompleted(Route r) {
        //Not used
    }

    @Override
    public void onTaskCompleted(CurrentWeather w) {
        currWeather = w;
        newPin.setCurrentWeather(currWeather);
        //txtWeatherInfo.setText(newPin.getCurrentWeather().getWeatherDesc());
        //txtNewPinWeatherInfoDegrees.setText(String.valueOf(newPin.getCurrentWeather().getTempC()) + "ºC");
        HttpHelper httpHelper = new HttpHelper();
        try {
            httpHelper.getBitmap(newPin.getCurrentWeather().getWeatherIconUrl(), this,this);
        } catch (OfflineModeException e) {
            e.printStackTrace();
        } catch (NoConnectionException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onTaskCompleted(Bitmap bmp) {
        FileHelper fileHelper = new FileHelper(this);
        File weatherIcon = fileHelper.saveWeatherIcon();
        ThumbnailsHelper.saveBitmap(bmp, weatherIcon);
        /*ImageView weatherIcon = new ImageView(this);
        weatherIcon.setImageBitmap(bmp);
        FrameLayout frameImage = (FrameLayout)findViewById(R.id.frmNewPinImage);
        frameImage.addView(weatherIcon);*/
    }

    private void populateNewTrip() {
        trip.setTitle(((TextView) findViewById(R.id.new_pin_edit_title)).getText().toString());
        trip.setStatus(TRIP_STATUS.RUNNING.getValue());
        if (((GlobalState)getApplicationContext()).getLoggedLocalUser() != null)
            trip.setUserId(((GlobalState)getApplicationContext()).getLoggedLocalUser().getId());
    }

    public void populateNewPin() {
        newPin.setTitle(((TextView) findViewById(R.id.new_pin_edit_title)).getText().toString());
        newPin.setTextNote(((EditText) findViewById(R.id.new_pin_edit_note)).getText().toString());
        newPin.setId(pinDao.persist(trip.getId(), newPin));

    }
    private boolean validateLatLng()
    {
        LatLng zeroLatLng = new LatLng(0,0);
        if(newPin.getLatLng() == null || newPin.getLatLng().equals(zeroLatLng))
        {
            newPin.setLatLng(locationHelper.getPosition());
            if(newPin.getLatLng() == null || newPin.getLatLng().equals(zeroLatLng))
            {
                Toast.makeText(this, "Localização indefinida. Ative o GPS seu inútil.", Toast.LENGTH_LONG).show();
                return false;
            }
        }
        return true;
    }

    public void saveFinish(){

        if(validateLatLng()){
            database = dbHelper.getWritableDatabase();
            if(trip.getId() == -1)
            {
                populateNewTrip();
                TripDAO tripDAO = new TripDAO(database);
                trip.setId(tripDAO.persist(trip));
                Intent backgroundPinGeneratorService = new Intent(this, BackgroundPinGeneratorService.class);
                startService(backgroundPinGeneratorService);

            }

            pinDao = new PinDAO(database);
            populateNewPin();
            FileHelper fileHelper = new FileHelper(this);
            fileHelper.persistTempFiles(trip.getId(), newPin.getId());
            for(Attachment att : newPin.getAttachments())
            {
                if(att.getContact()==null)
                    att.setPath(fileHelper.getAttachmentsDirectory(trip.getId(),newPin.getId()).getPath() + "/" + att.getFileName());
            }
            AttachmentDAO attachmentDAO = new AttachmentDAO(database);
            attachmentDAO.persist(newPin.getId(), newPin.getAttachments());

            if(purpose == ConstantsHelper.PIN_FINISH)
            {
                trip.setStatus(TRIP_STATUS.FINISHED.getValue());

                tripDao = new TripDAO(database);
                tripDao.persist(trip);
            }

            database.close();
            finish();
        }
    }



    @Override
    public boolean onOptionsItemSelected(MenuItem item) {

        switch (item.getItemId()) {
            case R.id.menu_att_camera:
                takePicture();
                return true;
            case R.id.menu_att_camera_video:
                recordVideo();
                return true;
            case R.id.menu_att_contact:
                //meetContact();
                Intent intent = new Intent();
                intent.setAction(Intent.ACTION_PICK);
                intent.setType("image/*");
                startActivityForResult(intent, ConstantsHelper.PICK_IMAGE_ACTIVITY_REQUEST_CODE);
                return true;
            /*case R.id.menu_att_voice:
                recordAudio();
                return true;*/
            default:
                DrawerLayout leftMenu = (DrawerLayout)findViewById(R.id.drawer_layout);
                ListView listMenu = (ListView)findViewById(R.id.left_drawer);
                if(leftMenu.isDrawerOpen(listMenu))
                    leftMenu.closeDrawer(listMenu);
                else
                    leftMenu.openDrawer(listMenu);
                return true;
        }
    }

    public void takePicture() {
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        FileHelper fileHelper = new FileHelper(this);
        fileUri = fileHelper.saveFile(FILE_TYPE.IMAGE);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
        // start the image capture Intent
        startActivityForResult(intent, ConstantsHelper.CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);

    }
    public void recordVideo() {
        FileHelper fileHelper = new FileHelper(this);
        Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
        fileUri = fileHelper.saveFile(FILE_TYPE.VIDEO);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri); // set the image file name
        intent.putExtra("FILE_TYPE", FILE_TYPE.VIDEO.getValue());
        // start the image capture Intent
        startActivityForResult(intent,ConstantsHelper.CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE);

    }
    public void recordAudio() {
        Intent intent = new Intent(MediaStore.Audio.Media.RECORD_SOUND_ACTION);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri); // set the image file name
        startActivityForResult(intent,ConstantsHelper.CAPTURE_AUDIO_ACTIVITY_REQUEST_CODE);


    }
    private void meetContact() {
        OpenContactsDialog dialog = new OpenContactsDialog();
        dialog.show(this.getFragmentManager(), "TAG");
    }


    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == Activity.RESULT_OK) {
            Attachment att = new Attachment();
            Contact contact;
            FileHelper fileHelper;
            switch(requestCode){
                case ConstantsHelper.CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE:
                    att.setPath(fileUri.getPath());
                    att.setFileType(FILE_TYPE.IMAGE.getValue());
                    try{
                        ThumbnailsHelper.generateThumbnail(new File(att.getPath()),FILE_TYPE.IMAGE,this);
                    }catch(Exception ex){}
                    newPin.addAttachment(att);
                    break;
                case ConstantsHelper.CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE:
                    att.setPath(fileUri.getPath());
                    att.setFileType(FILE_TYPE.VIDEO.getValue());
                    try{
                        ThumbnailsHelper.generateThumbnail(new File(att.getPath()), FILE_TYPE.VIDEO,this);
                    }catch(Exception ex){}
                    newPin.addAttachment(att);
                    break;
                case ConstantsHelper.CAPTURE_AUDIO_ACTIVITY_REQUEST_CODE:
                    String path = getAudioFilePathFromUri(data.getData());
                    fileHelper = new FileHelper(this);
                    File tempDir = fileHelper.getAttachmentsTemporaryDirectory();
                    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
                    File tempFile = new File(tempDir.getPath() + "/AUD_" + timeStamp + path.substring(path.lastIndexOf(".")));
                    fileHelper.moveFile(path, tempFile.getPath());
                    att.setPath(tempFile.getPath());
                    att.setFileType(FILE_TYPE.AUDIO.getValue());
                    newPin.addAttachment(att);
                    break;
                case ConstantsHelper.CONTACTS_ACTIVITY_REQUEST_CODE:
                    contact = new Contact();
                    Uri contactUri = data.getData();
                    String id = contactUri.getLastPathSegment();
                    Cursor basicInfo = getContentResolver().query(
                            ContactsContract.Contacts.CONTENT_URI
                            ,null
                            , ContactsContract.Contacts.Data._ID + "=?"
                            , new String[]{id}
                            , null);


                    int nameIdx = basicInfo.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME);
                    int pictureIdx = basicInfo.getColumnIndex(ContactsContract.Contacts.PHOTO_THUMBNAIL_URI);
                    int phoneNumberIdx = basicInfo.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
                    int emailIdx = basicInfo.getColumnIndex(ContactsContract.CommonDataKinds.Email.ADDRESS);
                    basicInfo.moveToFirst();
                    if(!basicInfo.isAfterLast()){
                        contact.setName(basicInfo.getString(nameIdx));
                        contact.setPictureThumbnailPath(basicInfo.getString(pictureIdx));
                        contact.setPhoneNumber(basicInfo.getString(phoneNumberIdx));
                        contact.setEmail(basicInfo.getString(emailIdx));

                        if(new File(contact.getPictureThumbnailPath()).exists())
                            att.setPath(contact.getPictureThumbnailPath());
                        else
                            att.setPath("android.resource://com.android.tripsandpins.app/ic_contact_picture");
                        att.setContact(contact);
                        att.setFileType(FILE_TYPE.CONTACT.getValue());

                    }
                    newPin.addAttachment(att);
                    break;
                case ConstantsHelper.FACEBOOK_CONTACTS_ACTIVITY_REQUEST_CODE:
                    List<GraphUser> fbContacts = ((GlobalState)getApplication()).getSelectedUsers();
                    for(GraphUser user : fbContacts)
                    {
                        att = new Attachment();
                        att.setFileType(FILE_TYPE.CONTACT.getValue());
                        contact = new Contact();
                        contact.setContactIdOnSource(user.getId());
                        contact.setName(user.getName());
                        att.setContact(contact);
                        newPin.addAttachment(att);
                    }
                    break;
                case ConstantsHelper.PICK_IMAGE_ACTIVITY_REQUEST_CODE:

                    Uri selectedImage = data.getData();
                    String picturePath;
                    String[] projection = { MediaStore.Images.Media.DATA };
                    Cursor cursor = getContentResolver().query(selectedImage, projection, null, null, null);
                    if (cursor != null) {
                        int column_index = cursor
                                .getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
                        cursor.moveToFirst();
                        picturePath= cursor.getString(column_index);

                        fileHelper = new FileHelper(this);
                        Uri newFileUri = fileHelper.saveFile(FILE_TYPE.IMAGE, picturePath);
                        att.setPath(newFileUri.getPath());
                        att.setFileType(FILE_TYPE.IMAGE.getValue());
                        try{
                            ThumbnailsHelper.generateThumbnail(new File(att.getPath()),FILE_TYPE.IMAGE,this);
                        }catch(Exception ex){}
                        newPin.addAttachment(att);
                    }
                    break;
            }

            loadListAttachments();
        }
    }

    private String getAudioFilePathFromUri(Uri uri) {
        Cursor cursor = getContentResolver().query(uri, null, null, null, null);
        cursor.moveToFirst();
        int index = cursor.getColumnIndex(MediaStore.Audio.AudioColumns.DATA);
        return cursor.getString(index);
    }

    public void getContact(int index)
    {
        Intent intent;
        switch (index) {
            case 0:
                /*intent = new Intent(Intent.ACTION_INSERT);
                intent.setType(ContactsContract.Contacts.CONTENT_TYPE);

                startActivityForResult(intent, ConstantsHelper.CONTACTS_ACTIVITY_REQUEST_CODE);*/
                break;
            case 1:
                /*intent = new Intent(Intent.ACTION_PICK,ContactsContract.Contacts.CONTENT_URI);
                startActivityForResult(intent, ConstantsHelper.CONTACTS_ACTIVITY_REQUEST_CODE);*/
                break;
            case 2:
                intent = new Intent();
                intent.setData(ConstantsHelper.FRIEND_PICKER);
                intent.setClass(this, FacebookContactsActivity.class);
                startActivityForResult(intent, ConstantsHelper.FACEBOOK_CONTACTS_ACTIVITY_REQUEST_CODE);
            default:
                break;
        }
    }
    private class OpenContactsDialog extends DialogFragment {

        @Override
        public Dialog onCreateDialog(Bundle savedInstanceState) {
            AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
            builder.setTitle(R.string.dialog_meet_contact);
            builder.setItems(R.array.dialog_contact_options, new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int index) {
                    getContact(index);
                }
            });
            return builder.create();
        }
    }
}